﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using ChiDao.Business.Service.Impl;
using ChiDao.Site.Models;
using Ext.Net.MVC;
using Ext.Net;
using ChiDao.Business.Models.FlowProcessNew;
using System.Xml;
using System.Web.Script.Serialization;
using ChiDao.Business.Service;
using ChiDao.Component.Utils;
using System.Xml;
using System.Collections;


namespace ChiDao.Site.Web.Controllers
{
    [Export]
    public class ProcessNewController : BaseController
    {
        [Import]
        public IProcessNodeNewService ProcessNodeNewService { get; set; }
        [Import]
        public IBaklogTaskNewService BaklogTaskNewService { get; set; }
        [Import]
        public IProcessUtilsService ProcessUtilsService { get; set; }
        [Import]
        public IProcessedTaskService ProcessedTaskService { get; set; }
        [Import]
        public IFlowProcessGraphService FlowProcessGraphService { get; set; }
        [Import]
        public IHolidayRequestService HolidayRequestService { get; set; }

        public ActionResult CirculationProcessNew(string processCode, string processID, string handleState)
        {
            CirculationProcessNewView circulationProcessNewView = new CirculationProcessNewView();
            PassProcessNodeNewView passProcessNodeNewView = new PassProcessNodeNewView();
            circulationProcessNewView.ProcessID = processID;
            circulationProcessNewView.ProcessCode = processCode;
            string currentProcessNodeCode = string.Empty;
            string nodeXML = string.Empty;
            if (handleState == "0")
            {
                switch (processCode)
                {
                    case "HolidayRequest":
                        ProcessNodeNewView nodeNewView = ProcessNodeNewService.GetProcessNodeByNodeCode(processCode, true, "");
                        currentProcessNodeCode = nodeNewView.NodeCode;
                        nodeXML = nodeNewView.NodeXML;
                        break;
                }
            }
            else
            {
                currentProcessNodeCode = BaklogTaskNewService.GetBaklogTaskNew(User.Identity.Name, processID)[0].CurrentProcessNodeCode;
                nodeXML = ProcessNodeNewService.GetProcessNodeByNodeCode(processCode, false, currentProcessNodeCode).NodeXML;
            }
            circulationProcessNewView.CurrentProcessNodeCode = currentProcessNodeCode;
            XmlDocument docPerson = new XmlDocument();
            docPerson.LoadXml(nodeXML);
            XmlNode personConditionNode = docPerson.SelectSingleNode("NodeXML/personCondition");
            if (personConditionNode != null)
            {
                circulationProcessNewView.ProcessPersonCondition = personConditionNode.InnerText;
            }
            GetCirculationNodeCode(processCode, processID, nodeXML, circulationProcessNewView, passProcessNodeNewView);
            foreach (ProcessNodeNewView processNodeNewView in passProcessNodeNewView.lstPassProcessNodeNew)
            {
                processNodeNewView.NodeXML = "";
            }
            circulationProcessNewView.PassProcessNodeNewJson = JSON.Serialize(passProcessNodeNewView);
            return View(circulationProcessNewView);
        }

        private void GetCirculationNodeCode(string processCode, string processID, string nodeXML, CirculationProcessNewView circulationProcessNewView, PassProcessNodeNewView passProcessNodeNewView)
        {
            string processNodeCode = string.Empty;
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(nodeXML);
            XmlNodeList nodeList = doc.SelectNodes("NodeXML/circulationCell");
            if (nodeList.Count == 0)
            {
                nodeList = doc.SelectNodes("NodeXML/nextCell/cell1");
                processNodeCode = nodeList[0].InnerText;
            }
            else
            {
                string functionName = nodeList[0].SelectSingleNode("functionName").InnerText;
                XmlNode paraNode = nodeList[0].SelectSingleNode("functionParam");
                Hashtable para = new Hashtable();
                para.Add("ProcessID", processID);
                if (paraNode != null && paraNode.ChildNodes.Count > 0)
                {
                    foreach (XmlNode node in paraNode.ChildNodes)
                    {
                        para.Add(node.Name, node.InnerText);
                    }
                }
                processNodeCode = ProcessUtilsService.ExecuteCommand(functionName, para) as string;
            }
            ProcessNodeNewView processNodeNew = ProcessNodeNewService.GetProcessNodeByNodeCode(processCode, false, processNodeCode);
            if (processNodeNew.NodeType == "1")
            {
                passProcessNodeNewView.lstPassProcessNodeNew.Add(processNodeNew);
                GetCirculationNodeCode(processCode, processID, processNodeNew.NodeXML, circulationProcessNewView, passProcessNodeNewView);
            }
            else
            {
                if (!string.IsNullOrEmpty(processNodeNew.NodeXML))
                {
                    XmlDocument docPerson = new XmlDocument();
                    docPerson.LoadXml(processNodeNew.NodeXML);
                    XmlNodeList personNodeList = docPerson.SelectNodes("NodeXML/defaultProcessPerson");
                    string getType = personNodeList[0].SelectSingleNode("getType").InnerText;
                    if (getType == "value")
                    {
                        processNodeNew.DefaultProcessPerson = personNodeList[0].SelectSingleNode("presonList").InnerText;
                    }
                    else
                    {
                        string functionName = personNodeList[0].SelectSingleNode("functionName").InnerText;
                        XmlNode paraNode = personNodeList[0].SelectSingleNode("functionParam");
                        Hashtable para = new Hashtable();
                        para.Add("ProcessID", processID);
                        if (paraNode != null && paraNode.ChildNodes.Count > 0)
                        {
                            foreach (XmlNode node in paraNode.ChildNodes)
                            {
                                para.Add(node.Name, node.InnerText);
                            }
                        }
                        processNodeNew.DefaultProcessPerson = ProcessUtilsService.ExecuteCommand(functionName, para) as string;
                    }
                }
                circulationProcessNewView.lstCirculationProcessNodeNew.Add(processNodeNew);
            }
        }

        [DirectMethod]
        public ActionResult SaveCirculationData(string processID, string processCode, string currentProcessNodeCode, string processPersonCondition, string[] circulationDataList, string passNodeList, string approvalOpinion)
        {
            try
            {
                ProcessNodeNewView currentProcessNodeNew = ProcessNodeNewService.GetProcessNodeByNodeCode(processCode, false, currentProcessNodeCode);
                string circulationData = "{\"circulationData\":" + circulationDataList[0] + "}";
                XmlNode circulationDataNode = JSON.DeserializeXmlNode(circulationData);
                string nodeCode = circulationDataNode.SelectNodes("circulationData/NodeCode")[0].InnerText;
                string nodeName = circulationDataNode.SelectNodes("circulationData/NodeName")[0].InnerText;
                string processPersonStr = circulationDataNode.SelectNodes("circulationData/DefaultProcessPerson")[0].InnerText;

                #region 更新单据状态，获取申请人
                string requestPerson = string.Empty;
                bool isRequest = false;
                switch (processCode)
                {
                    case "HolidayRequest":
                        HolidayRequestView holidayRequestView = HolidayRequestService.GetHolidayRequestByID(processID);
                        requestPerson = holidayRequestView.RequestPerson;
                        if (holidayRequestView.HandleState == "0")
                        {
                            isRequest = true;
                            HolidayRequestService.UpdateHoliday(Guid.Parse(processID), "", DateTime.Now, DateTime.Now, "1", true);
                        }
                        if (nodeCode == "End")
                        {
                            HolidayRequestService.UpdateHoliday(Guid.Parse(processID), "", DateTime.Now, DateTime.Now, "2", true);
                        }
                        break;
                }
                #endregion

                #region 添加已办、添加流程经过节点、删除代办
                List<BaklogTaskNewView> originalList = BaklogTaskNewService.GetBaklogTaskNew(User.Identity.Name, processID);
                List<ProcessedTaskView> addProcessedTaskList = new List<ProcessedTaskView>();
                List<FlowProcessGraphView> addFlowProcessGraphViewList = new List<FlowProcessGraphView>();
                List<BaklogTaskNewView> deleteBaklogTaskNewList = new List<BaklogTaskNewView>();
                if (isRequest)
                {
                    addProcessedTaskList.Add(new ProcessedTaskView()
                    {
                        ID = Guid.NewGuid(),
                        ProcessID = processID,
                        CurrentProcessNodeCode = currentProcessNodeNew.NodeCode,
                        CurrentProcessNodeName = currentProcessNodeNew.NodeName,
                        ApprovalOpinion = approvalOpinion,
                        CurrentProcessPerson = User.Identity.Name,
                        ProcessTime = DateTime.Now
                    });

                    addFlowProcessGraphViewList.Add(new FlowProcessGraphView()
                    {
                        ID = Guid.NewGuid(),
                        ProcessID = processID,
                        PassProcessNodeCode = currentProcessNodeNew.NodeCode,
                        PassProcessNodeType = "1"
                    });
                }
                else
                {
                    if (!string.IsNullOrEmpty(processPersonCondition) && processPersonCondition == "and")
                    {
                        BaklogTaskNewView deleteInfo = originalList.Find(b => b.CurrentProcessPerson == User.Identity.Name);
                        deleteBaklogTaskNewList.Add(deleteInfo);

                        addProcessedTaskList.Add(new ProcessedTaskView()
                        {
                            ID = Guid.NewGuid(),
                            ProcessID = processID,
                            CurrentProcessNodeCode = currentProcessNodeNew.NodeCode,
                            CurrentProcessNodeName = currentProcessNodeNew.NodeName,
                            ApprovalOpinion = approvalOpinion,
                            CurrentProcessPerson = deleteInfo.CurrentProcessPerson,
                            ProcessTime = DateTime.Now
                        });

                        //if (originalList.Count == 1)
                        //{
                        //    addFlowProcessGraphViewList.Add(new FlowProcessGraphView()
                        //    {
                        //        ID = Guid.NewGuid(),
                        //        ProcessID = processID,
                        //        PassProcessNodeCode = currentProcessNodeNew.NodeCode,
                        //        PassProcessNodeType = "1"
                        //    });
                        //}
                    }
                    else
                    {
                        foreach (BaklogTaskNewView baklogTaskNewView in originalList)
                        {
                            deleteBaklogTaskNewList.Add(baklogTaskNewView);

                            if (baklogTaskNewView.CurrentProcessPerson == User.Identity.Name)
                            {
                                ProcessedTaskView processedTask = new ProcessedTaskView()
                                {
                                    ID = Guid.NewGuid(),
                                    ProcessID = processID,
                                    CurrentProcessNodeCode = currentProcessNodeNew.NodeCode,
                                    CurrentProcessNodeName = currentProcessNodeNew.NodeName,
                                    ApprovalOpinion = approvalOpinion,
                                    CurrentProcessPerson = baklogTaskNewView.CurrentProcessPerson,
                                    ProcessTime = DateTime.Now
                                };
                                addProcessedTaskList.Add(processedTask);
                            }
                        }

                        //addFlowProcessGraphViewList.Add(new FlowProcessGraphView()
                        //{
                        //    ID = Guid.NewGuid(),
                        //    ProcessID = processID,
                        //    PassProcessNodeCode = currentProcessNodeNew.NodeCode,
                        //    PassProcessNodeType = "1"
                        //});
                    }
                }
                BaklogTaskNewService.DeleteBaklogTaskNew(deleteBaklogTaskNewList);
                ProcessedTaskService.AddProcessedTask(addProcessedTaskList);
                XmlNode passNode = JSON.DeserializeXmlNode(passNodeList);
                foreach (XmlNode childNode in passNode.ChildNodes)
                {
                    addFlowProcessGraphViewList.Add(new FlowProcessGraphView()
                    {
                        ID = Guid.NewGuid(),
                        ProcessID = processID,
                        PassProcessNodeCode = childNode.SelectSingleNode("NodeCode").InnerText,
                        PassProcessNodeType = "1"
                    });
                }
                #endregion

                #region 添加待办，添加流程经过节点
                originalList = BaklogTaskNewService.GetBaklogTaskNew(User.Identity.Name, processID);
                if (nodeCode != "End" && originalList.Count == 0)
                {
                    List<BaklogTaskNewView> addList = new List<BaklogTaskNewView>();
                    string[] processPersonArr = processPersonStr.Split(',');
                    foreach (string processPerson in processPersonArr)
                    {
                        BaklogTaskNewView add = new BaklogTaskNewView();
                        add.ID = GuidHelper.NewGuid();
                        add.ProcessID = processID;
                        switch (processCode)
                        {
                            case "HolidayRequest":
                                add.TaskName = "请假单";
                                break;
                        }
                        add.TaskType = processCode;
                        add.RequestPerson = requestPerson;
                        add.CurrentProcessNodeCode = nodeCode;
                        add.CurrentProcessPerson = processPerson;
                        addList.Add(add);
                    }

                    addFlowProcessGraphViewList.Add(new FlowProcessGraphView()
                    {
                        ID = Guid.NewGuid(),
                        ProcessID = processID,
                        PassProcessNodeCode = nodeCode,
                        PassProcessNodeType = "1"
                    });

                    FlowProcessGraphService.AddFlowProcessGraph(addFlowProcessGraphViewList);
                    BaklogTaskNewService.AddBaklogTaskNew(addList);
                }
                #endregion

                X.Msg.Confirm("确认", "流程成功！", new MessageBoxButtonsConfig
                {
                    Ok = new MessageBoxButtonConfig { Handler = "window.parent.saveCirculationDataSuccess()", Text = "Ok" }
                }).Show();
            }
            catch (Exception ex)
            {
                X.Msg.Confirm("确认", "流转失败！", new MessageBoxButtonsConfig
                {
                    Ok = new MessageBoxButtonConfig { Text = "Ok" }
                }).Show();
            }
            return this.Direct();
        }
    }
}